crash_debug ?= n
frame_pointer ?= n
+# Allow some delicate passthrough related hypercalls to be made from a stubdom
+privileged_stubdoms ?= y
+
XEN_ROOT=$(BASEDIR)/..
include $(XEN_ROOT)/Config.mk
CFLAGS-y += -DMAX_PHYS_IRQS=$(max_phys_irqs)
endif
+ifeq ($(privileged_stubdoms),y)
+CFLAGS += -DPRIVILEGED_STUBDOMS
+endif
+
AFLAGS-y += -D__ASSEMBLY__
ALL_OBJS := $(ALL_OBJS-y)
ASSERT(spin_is_locked(&pcidevs_lock));
ASSERT(spin_is_locked(&d->event_lock));
- if ( !IS_PRIV(current->domain) )
+ if ( !STUBDOM_IS_PRIV_FOR(current->domain, d) )
return -EPERM;
if ( pirq < 0 || pirq >= d->nr_pirqs || irq < 0 || irq >= nr_irqs )
struct msi_info _msi;
void *map_data = NULL;
- if ( !IS_PRIV(current->domain) )
- return -EPERM;
-
if ( !map )
return -EINVAL;
d = rcu_lock_domain_by_id(map->domid);
if ( d == NULL )
+ return -ESRCH;
+
+ if ( !STUBDOM_IS_PRIV_FOR(current->domain, d) )
{
- ret = -ESRCH;
+ ret = -EPERM;
goto free_domain;
}
struct domain *d;
int ret;
- if ( !IS_PRIV(current->domain) )
- return -EPERM;
-
if ( unmap->domid == DOMID_SELF )
d = rcu_lock_domain(current->domain);
else
if ( d == NULL )
return -ESRCH;
+ ret = -EPERM;
+ if ( !STUBDOM_IS_PRIV_FOR(current->domain, d) )
+ goto free_domain;
+
spin_lock(&pcidevs_lock);
spin_lock(&d->event_lock);
ret = unmap_domain_pirq(d, unmap->pirq);
spin_unlock(&d->event_lock);
spin_unlock(&pcidevs_lock);
+free_domain:
rcu_unlock_domain(d);
-
return ret;
}
long ret = 0;
struct xen_domctl curop, *op = &curop;
- if ( !IS_PRIV(current->domain) )
- return -EPERM;
-
if ( copy_from_guest(op, u_domctl, 1) )
return -EFAULT;
if ( op->interface_version != XEN_DOMCTL_INTERFACE_VERSION )
return -EACCES;
+ switch ( op->cmd )
+ {
+ case XEN_DOMCTL_ioport_mapping:
+ case XEN_DOMCTL_memory_mapping:
+ case XEN_DOMCTL_bind_pt_irq:
+ case XEN_DOMCTL_unbind_pt_irq:
+ case XEN_DOMCTL_assign_device:
+ case XEN_DOMCTL_deassign_device: {
+ struct domain *d = get_domain_by_id(op->domain);
+ bool_t is_priv = IS_PRIV(current->domain);
+ if ( !is_priv && ((d = rcu_lock_domain_by_id(op->domain)) != NULL) )
+ {
+ is_priv = STUBDOM_IS_PRIV_FOR(current->domain, d);
+ rcu_unlock_domain(d);
+ }
+ if ( !is_priv )
+ return -EPERM;
+ break;
+ }
+ default:
+ if ( !IS_PRIV(current->domain) )
+ return -EPERM;
+ break;
+ }
+
if ( !domctl_lock_acquire() )
return hypercall_create_continuation(
__HYPERVISOR_domctl, "h", u_domctl);
#define __cpuinitdata
#define __cpuinit
+#ifdef PRIVILEGED_STUBDOMS
+#define STUBDOM_IS_PRIV_FOR(x,y) IS_PRIV_FOR(x,y)
+#else
+#define STUBDOM_IS_PRIV_FOR(x,y) IS_PRIV(x)
+#endif
+
#endif /* __XEN_CONFIG_H__ */